<?php
// ------------------------------------------------------------------------
// |@Author       : Jarmin <edshop@qq.com>
// |@----------------------------------------------------------------------
// |@Date         : 2023-07-04 15:23:46
// |@----------------------------------------------------------------------
// |@LastEditTime : 2023-07-04 15:25:39
// |@----------------------------------------------------------------------
// |@LastEditors  : Jarmin <jarmin@ladmin.cn>
// |@----------------------------------------------------------------------
// |@Description  : 
// |@----------------------------------------------------------------------
// |@FilePath     : Login.php
// |@----------------------------------------------------------------------
// |@Copyright (c) 2023 http://www.ladmin.cn   All rights reserved. 
// ------------------------------------------------------------------------
namespace app\login\logic;

use think\admin\extend\CodeExtend;
use think\admin\Logic;

/**
 * 登陆逻辑类，用于实现登陆相关的业务逻辑操作。
 */
class Login extends Logic
{
    /**
     * 用户登录
     * @param array $data 登录数据
     * @return array 登录结果，包含 code 状态码、message 提示信息和 data 数据
    */
    public function login(array $data)
    {
        // 根据用户名、邮箱或电话号码查询用户信息
        $user = $this->modelSystemUser->getOne(['username|email|phone' => $data['username']]);
        // 判断用户信息是否存在，不存在则返回提示信息
        if (!$user) return $this->json(RECORD_NOT_FOUND, lang('user.user_not_found'));
        // 判断用户是否被禁用，若被禁用则返回提示信息
        if ($user->status === 0) return $this->json(NUMBER_MATCH_ERROR, lang('user.user_banned'));
        // 验证用户名与密码的正确性，若密码不正确则返回错误提示
        if (CodeExtend::encryptPassword($data['password'], $user->salt) !== $user->password) return $this->json(STRING_MATCH_ERROR, lang('user.user_password_fail'));
        // 防止密码盐暴露，对密码盐进行MD5加密
        $user->salt = CodeExtend::md5ShaEncrypt($user->salt);
        // 生成唯一的 Token
        $token = CodeExtend::generateToken();
        // 判断用户是否已经登录，若已登录则将之前的 Token 终止
        $is_login = cache('user_info:' . $user->id);
        if ($is_login) $this->logout($token);
        // 判断是不是超级管理员，如果是超级管理员则获取全部角色ID
        if ($user->id === 1) {
            $user->role_list = json_encode($this->modelSystemRole->getColumnByWhere([],'id'));
        }
        // 将 Token 存储到 Redis 缓存中
        $user->token_time = $data['expires'];
        cache('user_info:' . $user->id, $token, $data['expires']);
        cache('user_info:' . $token, $user->toArray(), $data['expires']);
        try {
            // 尝试更新数据库中的 login_token 字段
            $this->modelSystemUser->updateById($user->id, ['login_token' => $token]);
            // 将用户信息存储到请求对象中，方便后续处理
            $this->app->request->user_info = $user->toArray();
            // 登陆成功，写入日志
            // $this->serviceSystem->setLog(SUCCESS, 'info', lang('log.user_login'), lang('log.login_user', ['user' => $data['username']]));
            // 更新成功，则返回相应的数据以及新生成的 Token
            return $this->json(SUCCESS, lang('user.user_login_success'), ['token' => $token, 'user_info' => $user->toArray()]);
        } catch (\Exception $e) {
            // 更新失败，输出错误日志，并返回错误信息
            // $this->seviceSystem->setLog($e->getCode(), 'error', $e->getMessage(), lang('log.login_error', ['message'=> $e->getMessage()]));
            return $this->json($e->getCode(), $e->getMessage());
        }
    }

    /**
     * 用户退出登录
     * @param string $token 用户 Token
     * @return array 退出结果，包含 code 状态码、message 提示信息和 data 数据
     */
    public function logout(string $token)
    {
        // 从 Redis 缓存中获取用户信息
        $user = cache('user_info:' . $token);
        if (!$user) return $this->json(NOT_EXISTS, lang('user.user_not_login'));
        // 清除绑定用户 ID 的缓存与 Token 对应的缓存信息
        cache('user_info:' . $user['id'], NULL);
        cache('user_info:' . $token,      NULL);
        return $this->json(SUCCESS, lang('user.exit_login_success'));
    }

    /**
     * 获取系统版本
     * @return void
     */
    public function getVer()
    {
        return $this->json(SUCCESS, lang('user.get_vertion_success'), ['ver'=>'1.6.9']);
    }

    /**
     * 获取用户菜单和所属角色权限信息
     * @param string $token 用户 token
     * @return array 获取到的菜单和角色信息
     */
    public function getMenus(string $token)
    {
        // 从缓存中获取用户信息
        $user = cache('user_info:' . $token);
        if (!$user) return $this->json(LOGIN_ERROR, lang('user.user_not_login'));
        // 根据用户信息获取菜单和所属角色权限信息
        $menus = $this->logicMenu->getMenuList($user['id'], json_decode($user['role_list']));
        if ($menus['code'] !== SUCCESS) return $this->json($menus['code'], $menus['message']);
        $menus['data']['dashboardGrid'] = $this->logicRole->getRoleInfo($user['id'], json_decode($user['role_list']));
        // 将api_auth 写入redis缓存
        $user['api_auth'] = $menus['data']['api_auth'];
        cache('user_info:' . $token, $user, $user['token_time']);
        unset($menus['data']['api_auth']);
        // 返回获取到的数据
        return $this->json(SUCCESS,lang('user.get_menu_list_success'), $menus['data']);
    }
}